﻿using Basic.FormCollect;
using Basic.FormCollect.Model;
using Basic.FormModel.PageLayout;
using Basic.FormModel.QueryColumn;
using Basic.FormRemoteModel;
using Basic.FormRemoteModel.PageLayout.Model;
using Basic.FormRemoteModel.PageLayout.Statistics;
using Basic.UserFormService.Interface;
using Basic.UserFormService.Model;
using SqlSugar;
using WeDonekRpc.CacheClient.Interface;
using WeDonekRpc.Helper;
using WeDonekRpc.SqlSugar.VirtualQuery;

namespace Basic.UserFormService.PageControl
{
    internal class StatisticsBodyCache
    {
        public StatisticsBody Result { get; set; }
        /// <summary>
        /// 筛选条件
        /// </summary>
        public PageFilterParam[] Where { get; set; }
    }
    internal class PageStatisticsService : PageControlService, IPageStatisticsService
    {
        private readonly ICustomPageLayoutCollect _Layout;
        private readonly IPhysicsQueryBodyCollect _QueryTable;
        private readonly ILocalCacheController _Cache;
        public PageStatisticsService ( ICustomPageLayoutCollect layout,
            ILocalCacheController cache,
            IPhysicsQueryBodyCollect queryTable )
        {
            this._Cache = cache;
            this._Layout = layout;
            this._QueryTable = queryTable;
        }
        private StatisticsControl _Control;
        private StatisticsBodyCache _GetBody ( long controlId )
        {
            PageLayoutDto layout = this._Layout.Get<PageLayoutDto>(controlId);
            if ( layout.ControlType != PageControlType.指标图 )
            {
                throw new ErrorException("form.page.control.type.error");
            }
            this._Control = layout.ControlConfig?.Statistics;
            if ( this._Control == null || this._Control.Select == null || this._Control.FormId.HasValue == false )
            {
                return new StatisticsBodyCache
                {
                    Result = new StatisticsBody
                    {
                        FormId = this._Control?.FormId,
                        PageId = layout.PageId,
                        Id = controlId
                    }
                };
            }
            this._Control = layout.ControlConfig.Statistics;
            StatisticsSelect select = this._Control.Select;
            PhysicsFormBody body = this._QueryTable.Get(this._Control.FormId.Value);
            long[] tableId = this._GetTableId();
            base._InitTable(body, tableId);
            string name = this._InitSelect(select);
            return new StatisticsBodyCache
            {
                Where = this._Control.Where,
                Result = new StatisticsBody
                {
                    FormId = this._Control.FormId,
                    PageId = layout.PageId,
                    Id = controlId,
                    Query = this._Query,
                    ColName = name,
                    Cols = this._Cols
                }
            };
        }
        public StatisticsBody Get ( long controlId, long companyId, Dictionary<string, string> extend )
        {
            string key = "StatisticsBody_" + controlId;
            if ( !this._Cache.TryGet(key, out StatisticsBodyCache body) )
            {
                body = this._GetBody(controlId);
                _ = this._Cache.Add(key, body, new TimeSpan(23, 0, 0));
            }
            StatisticsBody res = body.Result.Clone();
            res.Query.Where = body.Where.GetWhere(body.Result.Cols, companyId, extend);
            return res;
        }
        private long[] _GetTableId ()
        {
            if ( this._Control.Where.IsNull() )
            {
                return [this._Control.Select.TableId];
            }
            List<long> ids = new List<long>
            {
                this._Control.Select.TableId
            };
            this._Control.Where.ForEach(c =>
            {
                if ( c.Children.IsNull() )
                {
                    if ( c.TableId.HasValue )
                    {
                        ids.Add(c.TableId.Value);
                    }
                }
                else
                {
                    c.Children.ForEach(c =>
                    {
                        if ( c.TableId.HasValue )
                        {
                            ids.Add(c.TableId.Value);
                        }
                    });
                }
            });
            return ids.Distinct().ToArray();
        }
        private string _InitSelect ( StatisticsSelect c )
        {
            PhysicsQueryColumn col = this._column[c.ColumnId];
            SelectStruct sel = new SelectStruct
            {
                Name = col.ColName,
                Func = c.FuncType.GetQueryFuncType(out string format, out DateType? dateType),
                DateType = dateType,
                Format = format,
                Table = this._table[col.TableId].TableName
            };
            this._Query.Select = new SelectStruct[] { sel };
            return col.ColName;
        }


    }
}
